package pe.gob.mininter.dirandro.vaadin.panel.mantenimiento;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;

import pe.gob.mininter.dirandro.model.ModeloMarca;
import pe.gob.mininter.dirandro.model.Opcion;
import pe.gob.mininter.dirandro.service.ModeloMarcaService;
import pe.gob.mininter.dirandro.util.Constante;
import pe.gob.mininter.dirandro.vaadin.dialogs.ConfirmDialog;
import pe.gob.mininter.dirandro.vaadin.util.DirandroComponent;
import pe.gob.mininter.dirandro.vaadin.util.Injector;

import com.vaadin.annotations.AutoGenerated;
import com.vaadin.data.Item;
import com.vaadin.data.Property;
import com.vaadin.data.Property.ValueChangeEvent;
import com.vaadin.data.Property.ValueChangeListener;
import com.vaadin.data.util.BeanItemContainer;
import com.vaadin.data.util.HierarchicalContainer;
import com.vaadin.event.ShortcutAction.KeyCode;
import com.vaadin.event.ShortcutListener;
import com.vaadin.ui.Alignment;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Button.ClickListener;
import com.vaadin.ui.ComboBox;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.TextField;
import com.vaadin.ui.TreeTable;
import com.vaadin.ui.VerticalLayout;

public class PanelMantenModeloMarca extends DirandroComponent implements ClickListener{

	/*- VaadinEditorProperties={"grid":"RegularGrid,20","showGrid":true,"snapToGrid":true,"snapToObject":true,"movingGuides":false,"snappingDistance":10} */

	@AutoGenerated
	private VerticalLayout mainLayout;
	@AutoGenerated
	private HorizontalLayout PanelSecundario;
	@AutoGenerated
	private HorizontalLayout PanelContenido;
	@AutoGenerated
	private VerticalLayout PanelParametroContenido;
	@AutoGenerated
	private HorizontalLayout PanelBtnContenido;
	@AutoGenerated
	private Button btnEliminar;
	@AutoGenerated
	private Button btnCrear;
	@AutoGenerated
	private TextField txtModelo;
	@AutoGenerated
	private ComboBox cmbMarca;
	@AutoGenerated
	private ComboBox cmbTipo;
	@AutoGenerated
	private ComboBox cmbCategoria;
	@AutoGenerated
	private VerticalLayout PanelContieneTabla;
	@AutoGenerated
	private VerticalLayout PanelTabla;
	@AutoGenerated
	private TreeTable treeModeloMarca;
	@AutoGenerated
	private HorizontalLayout PanelFiltroTabla;
	@AutoGenerated
	private TextField txtFiltroModelo;
	
	private static final Logger logger = Logger.getLogger(PanelMantenModeloMarca.class);
	private static final long serialVersionUID = 6956146995873234612L;
	
	private ModeloMarcaService modeloMarcaService;
	private List<ModeloMarca> lstCategorias ;
	private List<ModeloMarca> lstTiposModeloMarca;
	private List<ModeloMarca> lstModeloMarca;
	
	private boolean flagNuevaEntidad;
	
	public PanelMantenModeloMarca(List<Opcion> acciones,String height) {
		super(acciones,height);
		modeloMarcaService = Injector.obtenerServicio(ModeloMarcaService.class);		
		buildMainLayout();
		setCompositionRoot(mainLayout);
		postConstruct();
	}

	@Override
	public void postConstruct() {
		lstCategorias = modeloMarcaService.buscarPadres();
		cmbCategoria.setInputPrompt("Categoria");
		cmbCategoria.setImmediate(true);
		cmbCategoria.setContainerDataSource(new BeanItemContainer<ModeloMarca>(ModeloMarca.class,  lstCategorias));		
		cmbCategoria.setItemCaptionPropertyId("nombre");
		cmbCategoria.addListener(new Property.ValueChangeListener() {            
			private static final long serialVersionUID = 1L;
			@Override
            public void valueChange(ValueChangeEvent event) {
				ModeloMarca modeloMarca = new ModeloMarca();
    			modeloMarca.setPadre((ModeloMarca)cmbCategoria.getValue());
    			lstTiposModeloMarca = modeloMarcaService.buscar(modeloMarca);
    			cmbTipo.setContainerDataSource(new BeanItemContainer<ModeloMarca>(ModeloMarca.class,lstTiposModeloMarca));
            }
        });

		cmbTipo.setItemCaptionPropertyId("nombre");
		cmbTipo.setImmediate(true);
		cmbTipo.setInputPrompt("Tipo");
		cmbTipo.addListener(new Property.ValueChangeListener() {            
			private static final long serialVersionUID = 1L;
			@Override
            public void valueChange(ValueChangeEvent event) {				 
				lstModeloMarca = null;
				if(cmbTipo.getValue() == null){
					lstModeloMarca = new ArrayList<ModeloMarca>();
				}else{
					ModeloMarca modeloMarca = new ModeloMarca();
					modeloMarca.setPadre((ModeloMarca)cmbTipo.getValue());
					lstModeloMarca = modeloMarcaService.buscar(modeloMarca);
				}
				cmbMarca.setContainerDataSource(new BeanItemContainer<ModeloMarca>(ModeloMarca.class,lstModeloMarca));
            }
        });
		
		cmbMarca.setImmediate(true);
		cmbMarca.setItemCaptionPropertyId("nombre");
		cmbMarca.setInputPrompt("Marca");
		
		btnCrear.setIcon(Constante.ICONOS.SAVE);
		btnEliminar.setIcon(Constante.ICONOS.DELETE);
		
		btnCrear.addListener((ClickListener)this);
		btnEliminar.addListener((ClickListener)this);
		
		txtFiltroModelo.addShortcutListener(new ShortcutListener("", KeyCode.ENTER, null) {			
			private static final long serialVersionUID = 4068232062569621771L;
			@Override
			public void handleAction(Object sender, Object target) {
				shortCutEnter(sender, target);
			}
		});
		
		treeModeloMarca.setSelectable(true);
		treeModeloMarca.setImmediate(true);
		treeModeloMarca.setNullSelectionAllowed(true);
		treeModeloMarca.setNullSelectionItemId(null);				
		
		treeModeloMarca.addListener(new ValueChangeListener() {
			
			private static final long serialVersionUID = -6124596484581515359L;

			@Override
			public void valueChange(ValueChangeEvent event) {
				boolean esModoNuevo = treeModeloMarca.getValue() == null;
				limpiar();
				if(esModoNuevo){
					//cmbCategoria.setEnabled(true);
					//cmbTipo.setEnabled(true);
					//cmbMarca.setEnabled(true);
					treeModeloMarca.setValue(null);
					habilitarEdicion(!esModoNuevo);
				}else {
					habilitarEdicion(!esModoNuevo);
					Item item = treeModeloMarca.getItem(treeModeloMarca.getValue());
				
					ModeloMarca modeloMarcaPadre = null;					
					if(item.getItemProperty("padre").getValue()!=null){
						//al menos segundo nivel
						modeloMarcaPadre = (ModeloMarca)item.getItemProperty("padre").getValue();						
						
						if(modeloMarcaPadre.getPadre()!=null){
							//al menos tercer nivel
							ModeloMarca superPadre = modeloMarcaService.obtener(modeloMarcaPadre.getPadre().getId());
							if(superPadre.getPadre()!=null){
								//cuarto nivel confirmado, cargar Categoria, TIpo y Marca
								recargarComboCategorias(superPadre.getPadre());
								recargarComboTipos(modeloMarcaPadre.getPadre());
								recargarComboMarca(modeloMarcaPadre);
							}else{
								//tercer nivel confirmado, cargar Categoria y Tipo
								recargarComboCategorias(modeloMarcaPadre.getPadre());
								recargarComboTipos(modeloMarcaPadre);
							}						
						}
						recargarComboCategorias(modeloMarcaPadre);
			
					}
					txtModelo.setValue(item.getItemProperty("nombre").getValue());
					//cmbCategoria.setEnabled(false);
					//cmbTipo.setEnabled(false);
					//cmbMarca.setEnabled(false);
				}				
			}
		});		
		refrescar();		
	}
	
	private void recargarComboCategorias(ModeloMarca categoria){

		for(ModeloMarca mom : lstCategorias){
			if(mom.getId().equals(categoria.getId())){
				cmbCategoria.select(mom);
    			lstTiposModeloMarca = modeloMarcaService.buscar(new ModeloMarca(mom));
    			cmbTipo.setContainerDataSource(new BeanItemContainer<ModeloMarca>(ModeloMarca.class,lstTiposModeloMarca));
    		}
		}
	
	}
	
	private void recargarComboTipos(ModeloMarca tipo){
		
		if(lstTiposModeloMarca!=null){
			for(ModeloMarca model : lstTiposModeloMarca){
				if(tipo.getId().equals(model.getId())){
					cmbTipo.select(model);
					lstModeloMarca = modeloMarcaService.buscar(new ModeloMarca(model));
					cmbMarca.setContainerDataSource(new BeanItemContainer<ModeloMarca>(ModeloMarca.class,lstModeloMarca));
				}
			}
		}
	}
	
	private void recargarComboMarca(ModeloMarca marca){
		
		for(ModeloMarca model : lstModeloMarca){
			if(marca.getId().equals(model.getId()))
			 cmbMarca.select(model);	
		}		
			
	}

	private void shortCutEnter(Object sender, Object target){
		ModeloMarca modeloMarca = null;
		List<ModeloMarca> lstModeloMarcas = new ArrayList<ModeloMarca>();
		if (StringUtils.isNotBlank(target.toString())) {
			modeloMarca = new ModeloMarca();
			modeloMarca.setPadre(new ModeloMarca());
			if(txtFiltroModelo.equals(target)){
				if(StringUtils.isNotBlank(txtFiltroModelo.getValue().toString())){
					modeloMarca.setNombre(txtFiltroModelo.getValue().toString());
				}				
			}
			lstModeloMarcas = modeloMarcaService.buscarPadreHijos(modeloMarca);
			Map<String,List<ModeloMarca>> map = modeloMarcaService.filtrarModelosMarcas(lstModeloMarcas);				
			cargarModeloMarca(map);				
		}else {
			refrescar();
		}
	}

	private void habilitarEdicion(boolean flag){
		flagNuevaEntidad = !flag;
		btnEliminar.setVisible(flag);
		if(flag){
			btnCrear.setCaption("Actualizar");
		}
		else{
			btnCrear.setCaption("Crear");
		}
	}
	
	public void limpiar(){
		txtModelo.setValue("");
		cmbCategoria.select(null);
		cmbMarca.select(null);
		cmbTipo.select(null); 
	}
	private void recorrer(String nombre, Map<String, List<ModeloMarca>> map, Long objPadre, HierarchicalContainer hwContainer) {//ok		
		Item item = null;
		for (ModeloMarca dependencia : map.get(nombre)) {			
			item = hwContainer.addItem(dependencia.getId());
			item.getItemProperty("id").setValue(dependencia.getId());
			item.getItemProperty("nombre").setValue(dependencia.getNombre());			
			item.getItemProperty("padre").setValue(dependencia.getPadre() == null ? null : dependencia.getPadre());
			item.getItemProperty("padre.id").setValue(dependencia.getPadre() == null ? null : dependencia.getPadre().getId());
			item.getItemProperty("tipo.nombre").setValue(dependencia.getPadre() == null ? null : dependencia.getPadre().getNombre());
			item.getItemProperty("tipo.id").setValue(dependencia.getPadre() == null ? null : dependencia.getPadre().getId());
			
			if (!nombre.equals(Constante.OPCION.KEY_PADRE)){
				hwContainer.setParent(dependencia.getId(), objPadre);
			}
			if (map.get(dependencia.getId().toString()) != null) {
				recorrer(dependencia.getId().toString(), map, dependencia.getId(),hwContainer);
			} else {
				hwContainer.setChildrenAllowed(dependencia.getId().toString(), false);
			}
		}
	}
	private void cargarModeloMarca(Map<String,List<ModeloMarca>> map ){
		HierarchicalContainer hwContainer = new HierarchicalContainer();
		hwContainer.addContainerProperty("id", Long.class, 0L);
		hwContainer.addContainerProperty("nombre", String.class, "");			
		hwContainer.addContainerProperty("padre", ModeloMarca.class, null);		
		hwContainer.addContainerProperty("padre.id", Long.class, 0L);
		hwContainer.addContainerProperty("tipo.nombre", String.class, 0L);
		hwContainer.addContainerProperty("tipo.id", Long.class, 0L);
		
		if(map.get(Constante.OPCION.KEY_PADRE) != null){
			recorrer(Constante.OPCION.KEY_PADRE, map, null, hwContainer);
		}
		treeModeloMarca.setContainerDataSource(hwContainer);		
		treeModeloMarca.setItemCaptionPropertyId("nombre");		
		treeModeloMarca.setVisibleColumns(new Object[]{"nombre"});
		treeModeloMarca.setColumnWidth("nombre", 385);
		
		for (Object id : treeModeloMarca.rootItemIds()){
			treeModeloMarca.setCollapsed(id, false);//expandItemsRecursively(id);
        }		
		for (Object itemId: treeModeloMarca.getItemIds())
			treeModeloMarca.setCollapsed(itemId, false);	
	}
	
	private void refrescar(){
		cmbCategoria.setEnabled(true);
		cmbTipo.setEnabled(true);
		cmbMarca.setEnabled(true);
		habilitarEdicion(false);
		limpiar();
		
		cmbCategoria.select(null);
		Map<String,List<ModeloMarca>> map = modeloMarcaService.listarModeloMarcas();
		cargarModeloMarca(map);
		
	}
	@Override
	public void buttonClick(ClickEvent event) {
		if(event.getButton().equals(btnCrear)){		
			ModeloMarca modeloMarca = new ModeloMarca();
			modeloMarca.setNombre((String)txtModelo.getValue());
			
			if (cmbCategoria.getValue() != null){
				modeloMarca.setPadre((ModeloMarca) cmbCategoria.getValue());
				if (cmbTipo.getValue() != null){
					modeloMarca.setPadre((ModeloMarca)cmbTipo.getValue());
					if( cmbMarca.getValue() != null ){
						modeloMarca.setPadre((ModeloMarca)cmbMarca.getValue());
					}
				}
			}
			
			modeloMarca.validar();
			if(flagNuevaEntidad){
				modeloMarcaService.crear(modeloMarca);				
			}
			else{
				Item item = treeModeloMarca.getItem(treeModeloMarca.getValue());				
				modeloMarca.setId(Long.parseLong(item.getItemProperty("id").getValue().toString()));
				modeloMarcaService.actualizar(modeloMarca);
			}
			refrescar();
			
		}
		if(event.getButton().equals(btnEliminar)){
			ConfirmDialog.show(getApplication().getMainWindow() , "¿Seguro de Eliminar el Registro?", new ConfirmDialog.Listener() {				
				private static final long serialVersionUID = 1L;
				public void onClose(ConfirmDialog dialog) {
	                if (dialog.isConfirmed()) {
	                	Item item = treeModeloMarca.getItem(treeModeloMarca.getValue());			
	        			modeloMarcaService.eliminarXId(Long.parseLong(item.getItemProperty("id").getValue().toString()));
	        			refrescar();
	                }
	            }
	        });
		}
	}

	@AutoGenerated
	private VerticalLayout buildMainLayout() {
		// common part: create layout
		mainLayout = new VerticalLayout();
		mainLayout.setImmediate(false);
		mainLayout.setWidth("100%");
		mainLayout.setHeight("-1px");
		mainLayout.setMargin(true);
		
		// top-level component properties
		setWidth("100.0%");
		setHeight("-1px");
		
		// PanelSecundario
		PanelSecundario = buildPanelSecundario();
		mainLayout.addComponent(PanelSecundario);
		mainLayout.setComponentAlignment(PanelSecundario, new Alignment(20));
		
		return mainLayout;
	}

	@AutoGenerated
	private HorizontalLayout buildPanelSecundario() {
		// common part: create layout
		PanelSecundario = new HorizontalLayout();
		PanelSecundario.setStyleName("whiteBackGround");
		PanelSecundario.setImmediate(false);
		PanelSecundario.setWidth("-1px");
		PanelSecundario.setHeight("-1px");
		PanelSecundario.setMargin(true);
		PanelSecundario.setSpacing(true);
		
		// PanelContenido
		PanelContenido = buildPanelContenido();
		PanelSecundario.addComponent(PanelContenido);
		PanelSecundario
				.setComponentAlignment(PanelContenido, new Alignment(20));
		
		return PanelSecundario;
	}

	@AutoGenerated
	private HorizontalLayout buildPanelContenido() {
		// common part: create layout
		PanelContenido = new HorizontalLayout();
		PanelContenido.setImmediate(false);
		PanelContenido.setWidth("690px");
		PanelContenido.setHeight("-1px");
		PanelContenido.setMargin(false);
		PanelContenido.setSpacing(true);
		
		// PanelContieneTabla
		PanelContieneTabla = buildPanelContieneTabla();
		PanelContenido.addComponent(PanelContieneTabla);
		
		// PanelParametroContenido
		PanelParametroContenido = buildPanelParametroContenido();
		PanelContenido.addComponent(PanelParametroContenido);
		
		return PanelContenido;
	}

	@AutoGenerated
	private VerticalLayout buildPanelContieneTabla() {
		// common part: create layout
		PanelContieneTabla = new VerticalLayout();
		PanelContieneTabla.setStyleName("h2");
		PanelContieneTabla.setCaption("Filtro de Busqueda");
		PanelContieneTabla.setImmediate(false);
		PanelContieneTabla.setWidth("420px");
		PanelContieneTabla.setHeight("324px");
		PanelContieneTabla.setMargin(false);
		
		// PanelFiltroTabla
		PanelFiltroTabla = buildPanelFiltroTabla();
		PanelContieneTabla.addComponent(PanelFiltroTabla);
		
		// PanelTabla
		PanelTabla = buildPanelTabla();
		PanelContieneTabla.addComponent(PanelTabla);
		
		return PanelContieneTabla;
	}

	@AutoGenerated
	private HorizontalLayout buildPanelFiltroTabla() {
		// common part: create layout
		PanelFiltroTabla = new HorizontalLayout();
		PanelFiltroTabla.setImmediate(false);
		PanelFiltroTabla.setWidth("-1px");
		PanelFiltroTabla.setHeight("-1px");
		PanelFiltroTabla.setMargin(false);
		
		// txtFiltroModelo
		txtFiltroModelo = new TextField();
		txtFiltroModelo.setImmediate(false);
		txtFiltroModelo.setWidth("420px");
		txtFiltroModelo.setHeight("-1px");
		txtFiltroModelo.setInputPrompt("Nombre");
		PanelFiltroTabla.addComponent(txtFiltroModelo);
		
		return PanelFiltroTabla;
	}

	@AutoGenerated
	private VerticalLayout buildPanelTabla() {
		// common part: create layout
		PanelTabla = new VerticalLayout();
		PanelTabla.setImmediate(false);
		PanelTabla.setWidth("-1px");
		PanelTabla.setHeight("-1px");
		PanelTabla.setMargin(false);
		
		// treeModeloMarca
		treeModeloMarca = new TreeTable();
		treeModeloMarca.setImmediate(false);
		treeModeloMarca.setWidth("420px");
		treeModeloMarca.setHeight("300px");
		PanelTabla.addComponent(treeModeloMarca);
		
		return PanelTabla;
	}

	@AutoGenerated
	private VerticalLayout buildPanelParametroContenido() {
		// common part: create layout
		PanelParametroContenido = new VerticalLayout();
		PanelParametroContenido.setStyleName("h2");
		PanelParametroContenido.setCaption("Administración de Tabla Generica");
		PanelParametroContenido.setImmediate(false);
		PanelParametroContenido.setWidth("-1px");
		PanelParametroContenido.setHeight("-1px");
		PanelParametroContenido.setMargin(false);
		PanelParametroContenido.setSpacing(true);
		
		// cmbCategoria
		cmbCategoria = new ComboBox();
		cmbCategoria.setCaption("Categoria");
		cmbCategoria.setImmediate(false);
		cmbCategoria.setWidth("-1px");
		cmbCategoria.setHeight("-1px");
		PanelParametroContenido.addComponent(cmbCategoria);
		
		// cmbTipo
		cmbTipo = new ComboBox();
		cmbTipo.setCaption("Tipo");
		cmbTipo.setImmediate(false);
		cmbTipo.setWidth("-1px");
		cmbTipo.setHeight("-1px");
		PanelParametroContenido.addComponent(cmbTipo);
		
		// cmbMarca
		cmbMarca = new ComboBox();
		cmbMarca.setCaption("Marca");
		cmbMarca.setImmediate(false);
		cmbMarca.setWidth("-1px");
		cmbMarca.setHeight("-1px");
		PanelParametroContenido.addComponent(cmbMarca);
		
		// txtModelo
		txtModelo = new TextField();
		txtModelo.setCaption("Descripción");
		txtModelo.setImmediate(false);
		txtModelo.setWidth("250px");
		txtModelo.setHeight("-1px");
		txtModelo.setRequired(true);
		txtModelo.setInputPrompt("Descripción");
		PanelParametroContenido.addComponent(txtModelo);
		
		// PanelBtnContenido
		PanelBtnContenido = buildPanelBtnContenido();
		PanelParametroContenido.addComponent(PanelBtnContenido);
		PanelParametroContenido.setComponentAlignment(PanelBtnContenido,
				new Alignment(10));
		
		return PanelParametroContenido;
	}

	@AutoGenerated
	private HorizontalLayout buildPanelBtnContenido() {
		// common part: create layout
		PanelBtnContenido = new HorizontalLayout();
		PanelBtnContenido.setImmediate(false);
		PanelBtnContenido.setWidth("220px");
		PanelBtnContenido.setHeight("62px");
		PanelBtnContenido.setMargin(true);
		
		// btnCrear
		btnCrear = new Button();
		btnCrear.setCaption("Crear");
		btnCrear.setImmediate(true);
		btnCrear.setWidth("-1px");
		btnCrear.setHeight("-1px");
		PanelBtnContenido.addComponent(btnCrear);
		
		// btnEliminar
		btnEliminar = new Button();
		btnEliminar.setCaption("Eiminar");
		btnEliminar.setImmediate(true);
		btnEliminar.setWidth("-1px");
		btnEliminar.setHeight("-1px");
		PanelBtnContenido.addComponent(btnEliminar);
		
		return PanelBtnContenido;
	}
}